//import java.util.ArrayList;
//import java.util.HashSet;
//import java.util.Iterator;
//
//
///** a Node is a intermediate state of the backtrack algorithm
// * 
// * @author romain
// * @version 0
// */
//public class Node {
//	
////	private Board actualboard;             //Actual board
//	private HashSet<Move> performedMoves;  //Tried moves from this board
//	private Move prevMove;                 //Last move which has generate the board
//	private ArrayList<Position> freeGoals; //targets of the boxes
//	private Move nextMove;
//	private static int nb=0;
//	private PlayerNBoxes playerNBoxes;
//	
//	
//	/** Constructor for the initial node
//	 */
//	public Node(Board b, PlayerNBoxes playerNBoxes){
//		this.performedMoves = new HashSet<Move>();
//		this.freeGoals = new ArrayList<Position>();
//		for (int i=0;i<b.getNumRows();i++){
//        	for (int j=0;j<b.getNumColumns();j++){
//        		byte ij = b.getData(i, j);
//        		if ((ij&Board.GOAL) !=0) this.freeGoals.add(new Position(i,j));
//        	} 
//        }
//		Node.nb++;		
//		this.playerNBoxes = playerNBoxes;
//	}
//	
//	/** Constructor for other nodes
//	 * @param m move which leads to the new board
//	 * @throws CloneNotSupportedException 
//	 */
//	public Node(Board b, Move m, PlayerNBoxes playerNBoxes, HashSet<Move> performedMoves) throws CloneNotSupportedException{
//		this.performedMoves = new HashSet<Move>();
//		this.freeGoals = new ArrayList<Position>();
//		Node.nb++;
//        for (int i=0;i<b.getNumRows();i++){
//        	for (int j=0;j<b.getNumColumns();j++){
//        		byte ij = b.getData(i, j);
//        		if ((ij&Board.GOAL) !=0) this.freeGoals.add(new Position(i,j));
//        	} 
//        } 
//        this.playerNBoxes = playerNBoxes.move(m);
//	}
//
//
//	public HashSet<Move> getPerformedMoves() {
//		return performedMoves;
//	}
//
//	public Move getPrevMove() {
//		return prevMove;
//	}
//
//	public PlayerNBoxes getPlayerNBoxes() {
//		return playerNBoxes;
//	}
//
//	public static int getNb() {
//		return nb;
//	}
//
//	public void print(){
//		System.out.println("\n***********NODE nb "+Node.nb+"*************");
//		System.out.println("size of performedMoves = "+this.performedMoves.size());
//		System.out.println(BtSearch.getBoard());
//		Helper.printjoint(Helper.joinBoards(BtSearch.getBoard(),this.playerNBoxes));
//	}
//	
//	public Move findBestMove(int[] signHash) throws CloneNotSupportedException {
//		this.nextMove = null;
//		Move bestMove = null;
//		int i=0;
//		int bestScore=100;
//		while(i<this.playerNBoxes.getBoxes().length){
//			Position p = this.playerNBoxes.getBoxes()[i];
//			System.out.println("box in "+p);
////			bestMove = new Move(p,Move.MOVE_RIGHT); // to make the function not to return null
//			// move right or left
//			System.out.println((BtSearch.getBoard().getData(p.getI()+1,p.getJ())&Board.WALL)==0);
//			System.out.println(this.playerNBoxes.getBoxAt(p.getI()+1,p.getJ())==null);
//			System.out.println((BtSearch.getBoard().getData(p.getI()-1,p.getJ())&Board.WALL)==0);
//			System.out.println(this.playerNBoxes.getBoxAt(p.getI()-1,p.getJ())==null);
//			if ((BtSearch.getBoard().getData(p.getI(),p.getJ()+1)&Board.WALL)==0
//					&& this.playerNBoxes.getBoxAt(p.getI(),p.getJ()+1)==null
//					&& (BtSearch.getBoard().getData(p.getI(),p.getJ()-1)&Board.WALL)==0
//					&& this.playerNBoxes.getBoxAt(p.getI(),p.getJ()-1)==null){
//				this.nextMove = new Move(p,Move.MOVE_RIGHT);
//				
//				if (EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes.move(nextMove),this.freeGoals,signHash)<bestScore
//						&& !contains(this.performedMoves,this.nextMove) && BoardSignature.isUnique(BtSearch.getBoard(),this.playerNBoxes,signHash)
//						&& PathFinding.isPathTo(new Position(p.getI(),p.getJ()-1), this.playerNBoxes, BtSearch.getBoard())){
//					bestMove = new Move(p,Move.MOVE_RIGHT);
//					System.out.println("move RIGHT");
//					bestScore = EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes,this.freeGoals,signHash);
//				}
//				this.nextMove = new Move(p,Move.MOVE_LEFT);
//				if (EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes.move(nextMove),this.freeGoals,signHash)<bestScore
//						&& !contains(this.performedMoves,this.nextMove)
//						&& BoardSignature.isUnique(BtSearch.getBoard(),this.playerNBoxes,signHash)
//						&& PathFinding.isPathTo(new Position(p.getI(),p.getJ()+1), this.playerNBoxes, BtSearch.getBoard())){
//					bestMove = new Move(p,Move.MOVE_LEFT);
//					System.out.println("move LEFT");
//					bestScore = EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes,this.freeGoals,signHash);
//				}
//			}
//			// move up or down
//			
//			if ((BtSearch.getBoard().getData(p.getI()+1,p.getJ())&Board.WALL)==0
//					&& this.playerNBoxes.getBoxAt(p.getI()+1,p.getJ())==null
//					&& (BtSearch.getBoard().getData(p.getI()-1,p.getJ())&Board.WALL)==0
//					&& this.playerNBoxes.getBoxAt(p.getI()-1,p.getJ())==null){
//				this.nextMove = new Move(p,Move.MOVE_DOWN);
//				if (EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes.move(nextMove),this.freeGoals,signHash)<bestScore
//						&& !contains(this.performedMoves,this.nextMove)
//						&& BoardSignature.isUnique(BtSearch.getBoard(),this.playerNBoxes,signHash)
//						&& PathFinding.isPathTo(new Position(p.getI()-1,p.getJ()), this.playerNBoxes, BtSearch.getBoard())){
//					bestMove = new Move(p,Move.MOVE_DOWN);
//					bestScore = EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes,this.freeGoals,signHash);
//				}
//				this.nextMove = new Move(p,Move.MOVE_UP);
//				System.out.println(EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes.move(nextMove),this.freeGoals,signHash)<bestScore);
//				System.out.println(!contains(this.performedMoves,this.nextMove));
//				System.out.println(BoardSignature.isUnique(BtSearch.getBoard(),this.playerNBoxes,signHash));
//				System.out.println(PathFinding.isPathTo(new Position(p.getI()+1,p.getJ()), this.playerNBoxes, BtSearch.getBoard()));
//				System.out.println(new Position(p.getI()+1,p.getJ()));
//				if (EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes.move(nextMove),this.freeGoals,signHash)<bestScore
//						&& !contains(this.performedMoves,this.nextMove)
//						&& BoardSignature.isUnique(BtSearch.getBoard(),this.playerNBoxes,signHash)
//						&& PathFinding.isPathTo(new Position(p.getI()+1,p.getJ()), this.playerNBoxes, BtSearch.getBoard())){
//					bestMove = new Move(p,Move.MOVE_UP);
//					bestScore = EvaluateBoard.getScore(BtSearch.getBoard(), this.playerNBoxes,this.freeGoals,signHash);
//				}
//			}
//			i++;
//		}
//		if (bestMove != null)
//			if(bestScore==100)bestMove.setValid(false);
//		System.out.println("bestMove score "+bestScore);
//		return bestMove;
//	}
//	
//	private boolean contains(HashSet<Move> list, Move m){
//		boolean answer = false;
//		Iterator<Move> itr = list.iterator();
//		while(itr.hasNext()) {
//			Move tmp = itr.next();
//			tmp.print();
//			if (tmp.isEquals(m)) answer = true;
//		}
//		return answer;
//	}
//	
//	public void addPerformedMove(Move m){
//		this.performedMoves.add(m);
//	}
//
//}
